DB账号防泄密,请立刻为数据库加把锁!(附演示视频)
作者介绍
贺春旸,普惠金融MySQL专家,《MySQL管理之道》第一版、第二版作者。曾任职于中国移动飞信、机锋安卓市场,拥有丰富的数据库管理经验。目前致力于MySQL、Linux等开源技术的研究。
一、技术实施背景
区别于传统型互联网公司,互联网金融公司对数据安全性要求较高。目前我们是用MariaDB的多源复制技术把线上的核心业务库同步过来,聚集成一个大的汇总库提供给数据模型部门分析数据,以及开发人员排查问题等。
由于业务日渐壮大,拥有DB账号的人数也越来越多,这里就存在着一个安全隐患:周末我们在咖啡厅连接数据库排查问题,如果被别人用嗅探工具监听,那么发生数据泄密的几率就会大大增加。
为了防止这种情况,我们就需要用SSL(Secure Sockets Layer 安全套接层协议)来实现客户端与服务器端之间的通信是进行加密的,没有了密钥,就无法解开加密的数据,从而保证通信的私密性。
二、安全连接概述
默认情况下客户端(PHP/JAVA等)连接MySQL/MariaDB传输数据是不加密的,可以通过下面的命令来验证这一点:
MariaDB [(none)]> SHOW VARIABLES LIKE 'have_ssl'; +---------------+----------+ | Variable_name | Value | +---------------+----------+ | have_ssl | DISABLED | +---------------+----------+ 1 row in set (0.00 sec) |
如果服务器支持安全连接,则值将设置为YES。如果未编译TLS模块,则值将设置为NO。DISABLED表示服务器已使用TLS模块进行编译,但未使用TLS模块启动,这通常是缺省情况。
你可以验证下TLS库是否动态链接,例:
# ldd `which mysqld` | grep ssl libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007fd6a7bce000) |
三、设置MariaDB SSL和安全客户端连接
SSL是利用密钥的加密技术(RSA)来作为用户端与服务器端在传送数据时的加密通讯协议。这里我们用通俗的语言来解释下这几个文件的含义:ca-cert.pem就是房产证,server-cert.pem就是门锁,client-key.pem就是钥匙。当你的证件齐全时,进到你家里才是合法的。
Step 1 - 升级OpenSSL
由于Centos6.8自带的OpenSSL版本太低,其自身的漏洞可能会带来安全隐患,故这里升级到最新版。
# wget https://www.openssl.org/source/openssl-1.1.0e.tar.gz # cd openssl-1.1.0e # ./config # make;make install # ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1 # ln -s /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1 # mv /usr/bin/openssl /usr/bin/openssl_bak # mv /usr/include/openssl /usr/include/openssl_bak # ln -s /usr/local/bin/openssl /usr/bin/openssl # ln -s /usr/local/include/openssl /usr/include/openssl |
默认是安装在/usr/local/bin/目录下。
Step 2 - 创建CA证书
# mkdir -p /etc/mysql/ssl/
# cd /etc/mysql/ssl/
1、创建CA证书颁发机构的密钥文件
# sudo /usr/local/bin/openssl genrsa 2048 > ca-key.pem
2、创建CA证书颁发机构的证书文件
# sudo /usr/local/bin/openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
注:Common Name (e.g. server FQDN or YOUR name) []:这里的名字不能有重复的,分表设置为:
CA common Name : MariaDB admin
Server common Name: MariaDB server
Client common Name: MariaDB client
Step 3 - 创建server端证书
1、创建server端密钥文件
# sudo /usr/local/bin/openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem
2、创建server端RSA密钥文件
# sudo /usr/local/bin/openssl rsa -in server-key.pem -out server-key.pem
3、创建server端证书
Step 4 - 创建client端证书
创建client端密钥文件
# sudo /usr/local/bin/openssl req -newkey rsa:2048 -days 7 -nodes
-keyout client-key.pem -out client-req.pem
注:-days 7是密钥有效期为7天,过期后失效。
2、创建client端RSA密钥文件
# sudo /usr/local/bin/openssl rsa -in client-key.pem -out client-key.pem
3、创建client端证书
#sudo /usr/local/bin/openssl x509 -req -in client-req.pem -days 7 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
注:-days 7是证书有效期为7天,过期后失效。
Step 5 - 如何验证证书?
#sudo /usr/local/bin/openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
注:如上图两个OK,代表成功。
Step 6 - MariaDB服务端开启SSL加密
1、编辑my.cnf添加如下参数
ssl ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/server-cert.pem ssl-key=/etc/mysql/ssl/server-key.pem |
注:在[mysqld]下面添加。
2、重启mysqld进程
# mysqladmin shutdown
# mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &
3、输入show variables like '%ssl%';查看是否生效,如出现下图的两个YES,代表成功开启SSL
Step 7 - MariaDB客户端使用SSL加密连接
1、创建SSL账号权限
> GRANT SELECT ON *.* TO 'demo'@'%' IDENTIFIED BY ‘demo’ REQUIRE SSL; |
2、mysql命令行登录连接
将ca-cert.pem文件、client-cert.pem文件、client-key.pem拷贝到客户端目录下,输入下面的命令进行登录连接:
# cd /etc/mysql/ssl
# mysql --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem
--ssl-key=client-key.pem -h192.168.143.244 -udemo -pdemo -P3308
没有密钥文件是无法连接的,如上图所示。
登录进去后,输入status命令,可以看到已经使用SSL信息:
3、Sqlyog/Navicat客户端登录连接
由于我是用最新的OpenSSL,所以Sqlyog/Navicat客户端也需要下载最新版本,才可以验证通过。
Sqlyog连接:
Navicat连接:
注:打个广告,谁有Navicat for MySQL v11.2.16的注册码?
Step 8 - SSL加密验证
1、使用360开源的MySQL Sniffer工具嗅探
测试结果:DB开启了SSL,mysql-sniffer工具失效,无法探测到传输数据
视频地址:http://pan.baidu.com/s/1kVzAvK7
2、使用tcpdump工具嗅探
注:感谢DBA邱文辉协同测试
# tcpdump -i em2 port 3308 -l -s 0 -w - | strings > 1.txt
1)用未加密用户连接,脚本:
#!/bin/bash while true do mysql -h192.168.143.244 -utest -ptest -P3308 -e "select * from sbtest1 limit 5;" sleep 1 done |
测试结果:
# more 1.txt(可以看到是明文传输的)
2)用SSL加密用户连接
测试结果:
# more 2.txt(可以看到是数据已经是乱码了,加密成功)
四、演示视频
云盘链接:http://pan.baidu.com/s/1kVzAvK7
相关专题:
◆ 近期热文 ◆
10款常见MySQL高可用方案选型解读
基于Docker的DevOps实现
深入浅出XTTS:Oracle数据库迁移升级利器
京东MySQL数据库Docker化最佳实践
性能优化利器:数据库审核平台的选型与实践
◆ MVP专栏 ◆